<template>
  <a-card :bordered="false" style="width: 100%">
    <!-- 自定义顶部搜索 -->
    <template #title>
      <div style="display: flex">
        <a-row class="a-row-search" :gutter="16">
          <a-col :lg="8">
            <span>角色名称：</span>
            <a-input
              style="width: 200px"
              v-model:value="searchRole.name"
              placeholder="角色名称"
            ></a-input>
          </a-col>
          <a-col :lg="8">
            <span>角色标识：</span>
            <a-input
              style="width: 200px"
              v-model:value="searchRole.code"
              placeholder="角色标识"
            ></a-input>
          </a-col>
          <a-col :lg="8">
            <span>角色状态：</span>
            <a-select
              placeholder="角色状态"
              ref="select"
              v-model:value="searchRole.status"
              style="width: 200px"
              @change="handleChange"
              :options="statusData"
            />
          </a-col>
        </a-row>
        <div class="right-btn">
          <a-space :size="40">
            <a-button
              v-permission="`permission:role:query`"
              type="primary"
              :loading="saveLoading"
              @click="handleSearch"
              >查询</a-button
            >
            <a-button
              @click="handleReset"
              v-permission="`permission:role:reset`"
              >重置</a-button
            >
          </a-space>
        </div>
      </div>
    </template>

    <!-- 新增角色区域 -->
    <div style="height: 60px">
      <a-button
        type="primary"
        v-permission="`permission:role:add`"
        @click="handlerAddRoleOpen"
      >
        <template #icon>
          <PlusCircleOutlined spin />
        </template>
        新增
      </a-button>
    </div>

    <!-- 角色表格数据 -->
    <a-table
      :scroll="{ x: 1300 }"
      :dataSource="tableData"
      :loading="loading"
      :pagination="false"
    >
      <a-table-column
        fixed="left"
        title="角色编号"
        dataIndex="id"
        :width="100"
      />
      <a-table-column title="角色名称" dataIndex="name" :width="120" />
      <a-table-column title="角色标识" dataIndex="code" :width="120" />
      <a-table-column title="状态" dataIndex="status" :width="100">
        <template #default="{ record }">
          <a-switch
            :disabled="record.code === 'admin'"
            v-model:checked="record.checked"
            @change="handleChangeStatus(record.id)"
          >
            <template #checkedChildren><check-outlined /></template>
            <template #unCheckedChildren><close-outlined /></template>
          </a-switch>
        </template>
      </a-table-column>
      <a-table-column title="创建时间" dataIndex="createTime" :width="140" />
      <a-table-column fixed="right" title="操作" :width="155">
        <template #default="{ record }">
          <a-button
            type="link"
            size="small"
            @click="handlerPermiOpen(record)"
            v-permission="`permission:role:assign`"
          >
            <SendOutlined spin />
            分配权限
          </a-button>
          <a-button
            v-permission="`permission:role:update`"
            type="link"
            size="small"
            @click="handleEchoRole(record.id)"
          >
            <FormOutlined />
            修改
          </a-button>
          <a-popconfirm
            placement="bottom"
            ok-text="确认"
            cancel-text="取消"
            title="确认删除该角色？"
            @confirm="handleRemoveRole(record.id)"
          >
            <a-button
              type="link"
              danger
              size="small"
              v-permission="`permission:role:delete`"
            >
              <DeleteOutlined />
              删除
            </a-button>
          </a-popconfirm>
        </template>
      </a-table-column>
    </a-table>

    <!-- 分页 -->
    <div class="pagination-style">
      <a-pagination
        @change="handlePaginationChange"
        v-model:current="pageNo"
        :pageSize="pageSize"
        :total="total"
      />
    </div>
  </a-card>

  <!-- 新增角色弹框 -->
  <a-modal
    @cancel="handlerCancel"
    v-model:open="addRoleOpen"
    width="30%"
    :title="role.id === undefined ? '添加角色' : '修改角色'"
    @ok="handleOk"
  >
    <a-form
      ref="formRef"
      :rules="rules"
      :model="role"
      :wrapper-col="wrapperCol"
      :labelCol="labelCol"
    >
      <a-form-item ref="name" label="角色名称" name="name">
        <a-input placeholder="角色名称" v-model:value="role.name" />
      </a-form-item>
      <a-form-item ref="code" label="角色标识" name="code">
        <a-input placeholder="角色标识" v-model:value="role.code" />
      </a-form-item>
    </a-form>

    <template #footer>
      <a-button
        key="submit"
        type="primary"
        :loading="saveLoading"
        @click="handleSaveRole"
        >确定</a-button
      >
      <a-button key="back" @click="handlerCancel">取消</a-button>
    </template>
  </a-modal>

  <!-- 分配权限抽屉 -->
  <a-drawer
    :closable="false"
    :width="380"
    title="分配权限"
    :placement="placement"
    :open="drawerOpen"
    @close="onClose"
  >
    <template #extra>
      <a-button style="margin-right: 10px" @click="onClose">取消</a-button>
      <a-button
        type="primary"
        :loading="saveLoading"
        @click="handlePermissionSave"
        >确定</a-button
      >
    </template>
    <div class="permisson-role">
      <span>角色分配：</span>
      <a-input
        v-model:value="roleName"
        disabled
        style="width: 220px; height: 33px"
      ></a-input>
    </div>
    <a-tree
      @check="handleCheck"
      ref="treeRef"
      defaultExpandAll
      v-model:checkedKeys="checkedKeys"
      checkable
      :tree-data="treeData"
    >
    </a-tree>
  </a-drawer>
</template>

<script setup>
import { ref, onMounted } from "vue";
import {
  queryRoleList,
  addRole,
  echoRole,
  updateRole,
  removeRole,
  updateRoleStatus,
  savePermission,
} from "@/api/role";
import { queryMenuListWithPermi, queryRoleMenuList } from "@/api/menu";
import { message } from "ant-design-vue";
import { ROLE_CONSTANT } from "@/constant/dictType.js";
import { queryDictLabel } from "@/api/dict_data";

const tableData = ref([]);
const treeData = ref([]);
const loading = ref(true);
const saveLoading = ref(false);
const pageNo = ref(1);
const pageSize = ref(10);
const total = ref(0);
const searchRole = ref({
  name: "",
  code: "",
  status: null,
});
const addRoleOpen = ref(false);
const drawerOpen = ref(false);
const role = ref({});
const roleName = ref("");
const checkedKeys = ref([]);
const treeRef = ref(null);
const statusData = ref([]);

onMounted(() => {
  getRoleList();
  getDictTypeStatus();
});

//获取角色数据
const getRoleList = () => {
  loading.value = true;
  queryRoleList(pageNo.value, pageSize.value, searchRole.value).then((res) => {
    if (res.code === 200 && res.data !== null) {
      tableData.value = res.data.data;
      total.value = res.data.total;
      loading.value = false;
    }
  });
};

//监听分页变化
const handlePaginationChange = (current, page) => {
  pageNo.value = current;
  pageSize.value = page;
  getRoleList();
};

//查询字典状态
const getDictTypeStatus = () => {
  queryDictLabel(ROLE_CONSTANT).then((res) => {
    if (res.code === 200) {
      statusData.value = res.data;
    }
  });
};

//获取菜单树形数据
const getMenuList = async () => {
  await queryMenuListWithPermi().then((res) => {
    if (res.code === 200) {
      treeData.value = res.data;
    }
  });
};

//重置
const handleReset = () => {
  searchRole.value = {
    name: "",
    code: "",
    status: null,
  };
  getRoleList();
};

//查询
const handleSearch = () => {
  if (
    searchRole.value.name !== "" ||
    searchRole.value.code !== "" ||
    searchRole.value.status !== null
  ) {
    saveLoading.value = true;
    getRoleList();
    saveLoading.value = false;
  }
};

//取消新增角色弹框
const handlerCancel = () => {
  addRoleOpen.value = false;
  role.value = {};
};

//新增角色弹框
const handlerAddRoleOpen = () => {
  addRoleOpen.value = true;
};

//新增、修改角色
const handleSaveRole = () => {
  formRef.value.validate().then(() => {
    saveLoading.value = true;
    if (role.value.id === undefined) {
      addRole(role.value).then((res) => {
        if (res.code === 200) {
          message.success("新增成功");
          addRoleOpen.value = false;
          saveLoading.value = false;
          role.value = {};
          getRoleList();
        } else {
          saveLoading.value = false;
        }
      });
    } else {
      updateRole(role.value).then((res) => {
        if (res.code === 200) {
          message.success("修改成功");
          addRoleOpen.value = false;
          saveLoading.value = false;
          role.value = {};
          getRoleList();
        } else {
          saveLoading.value = false;
        }
      });
    }
  });
};

//修改角色弹框
const handleEchoRole = (id) => {
  echoRole(id).then((res) => {
    if (res.code === 200) {
      role.value = res.data;
      addRoleOpen.value = true;
    }
  });
};

//删除角色
const handleRemoveRole = (id) => {
  removeRole(id).then((res) => {
    if (res.code === 200) {
      message.success("删除成功");
      getRoleList();
    }
  });
};

//修改角色状态
const handleChangeStatus = (id) => {
  updateRoleStatus(id).then((res) => {
    if (res.code === 200) {
      message.success("角色状态修改成功");
      getRoleList();
    }
  });
};

//关闭分配权限弹框
const onClose = () => {
  drawerOpen.value = false;
  checkedKeys.value = [];
};

//分配权限抽屉
const roleId = ref(null);
const handlerPermiOpen = (item) => {
  if (item.code === "admin") {
    message.warn("管理员不能分配权限");
  } else {
    roleName.value = item.name;
    roleId.value = item.id;
    //查询当前角色所拥有的权限
    gerCureentPermission(item.id);
  }
};

//查询当前角色所拥有的权限
const gerCureentPermission = async (id) => {
  await getMenuList();
  queryRoleMenuList(id).then((res) => {
    if (res.code === 200) {
      checkedKeys.value = res.data;
      drawerOpen.value = true;
    }
  });
};

//保存分配好的权限
const finalCheckedKeys = ref([]);
const handlePermissionSave = () => {
  saveLoading.value = true;
  savePermission(roleId.value, finalCheckedKeys.value).then((res) => {
    if (res.code === 200) {
      message.success("分配权限成功");
      drawerOpen.value = false;
      checkedKeys.value = [];
      saveLoading.value = false;
    } else {
      saveLoading.value = false;
    }
  });
};

const handleCheck = (checkedKey, e) => {
  finalCheckedKeys.value = checkedKey.concat(e.halfCheckedKeys);
};

const labelCol = {
  span: 6,
};
const wrapperCol = {
  span: 16,
};

const formRef = ref();
const rules = ref({
  name: [
    {
      required: true,
      message: "请输入角色名称",
      trigger: "change",
    },
  ],
  code: [
    {
      required: true,
      message: "请输入角色标识",
      trigger: "change",
    },
  ],
});
</script>
<style scoped lang='scss'>
.permisson-role {
  height: 80px;
  width: 100%;
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}

.a-row-search {
  height: 100px;
  width: 85%;
  display: flex;
  align-items: center;
}

.pagination-style {
  height: 120px;
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}

.right-btn {
  width: 15%;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
</style>